home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xnetbris.00
/
xnetbris
/
client-text.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-23
|
8KB
|
308 lines
/*
This is the text only client for Netbrisk (used mainly for debugging)
Copyright (C) 1995 Brendan Bartlett
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* The "protocol" for the server is as follows -
* - a packet of type INFORM_TYPE telling the client the numplayers and play_type
* - a MOVE_TYPE packet, with the brisk card in the card.
*
* - 3 MOVE_TYPE packets, giving the client the cards in their hand
*
* after the beginning point, the game is fairly normal with
* - packets of MOVE_TYPE or MESSAGE_TYPE
* - a very important packets of MOVE_EXPECTED tells the client that
* a move is expected from them now, and the server is idling.
*
*
* the client can do whatever they want with these packets
* "Fabio" and Brendan Bartlett, 1995
*/
/* Arggg!
* For the servers convience, the graphics are a little screwed up
* the card->weight:
* 9 ace
* 8 three
* 7 king (re)
* 6 girl (donna)
* .
* .
* .
*/
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include "brisk.h"
static int server_fd;
static int numplayers;
static int play_type;
static int my_number; /* which player number this client is */
static struct card brisk;
static struct card hand[3]; /* This is an array with the current cards in this players hand */
static int get_card(int); /* reads a new card from the server */
static void play_brisk(void);
static void update_cards(void); /* some sort of change to the hand -- tell the user */
int handler(int signum);
int start_client(char * hostname, int port);
void main(int, char *[]);
int handler(int signum)
{
fprintf(stderr, "got SIGPIPE, client cleaning..\n");
close(server_fd);
exit(0);
}
void main(int argc, char *argv[])
{
int port = 10000;
struct packet p;
int i;
signal(SIGPIPE, handler);
if(argc == 1)
{
printf("usage: %s <hostname> <port>\n", argv[0]);
printf(" hostname is the name where the SERVER is running.\n");
printf(" port is an optional setting to connect to the server.\n");
exit(0);
}
if(argc == 3)
port = atoi(argv[2]);
if(!start_client(argv[1], port))
{
printf("cannot connect to server '%s'\n", argv[1]);
exit(0);
}
/* Read in our hand from the server */
for(i = 0; i < 3; i++)
{
get_card(i);
printf(" %d %d \t", hand[i].suit, hand[i].weight);
}
/* Read in the brisk from the server */
read(server_fd, &p, sizeof(struct packet));
if(p.type != MOVE_TYPE || p.data.move.player != 5)
{
fprintf(stderr, "server did not send the brisk card!\n");
exit(0);
}
memcpy(&brisk, &p.data.move.play_card, sizeof(struct card));
printf("\nbrisk: %d %d\n", brisk.suit, brisk.weight);
printf("\n");
play_brisk();
}
/*
* This routine will read from the server for a packet of MOVE_TYPE (or DEAL_TYPE) and will fill in the
* given card in the hand[] array.
*
* If the packet is of type DEAL_TYPE, the argument 'card' is ignored and the suggested value in the
* packet is used instead.
*
* Returns 0 on failure
* 1 on success
*/
static int get_card(int card)
{
struct packet p;
read(server_fd, &p, sizeof(struct packet));
if( (p.type != MOVE_TYPE) && (p.type != DEAL_TYPE) )
{
fprintf(stderr, "FATAL ERROR: MOVE_TYPE or DEAL_TYPE expected!\n");
return 0;
}
if(p.type == DEAL_TYPE)
memcpy(&hand[p.data.deal.rec_place], &p.data.deal.deal_card, sizeof(struct card));
else
memcpy(&hand[card], &p.data.move.play_card, sizeof(struct card));
return 1;
}
/* *
* This updates the cards that the user sees on the scren.
*
*/
static void update_cards(void)
{
int i;
for(i = 0; i < 3; i++)
printf("%d %d \t", hand[i].suit, hand[i].weight);
printf("\n");
}
static void play_brisk(void)
{
struct packet in, out;
char buf[80];
int i;
while(1)
{
read(server_fd, &in, sizeof(struct packet));
switch(in.type)
{
case END_GAME:
printf("That's the end of the frigging game!\n");
close(server_fd);
exit(0);
case MESSAGE_TYPE:
printf("message: [%s]\n", in.data.message.string);
break;
case MOVE_TYPE:
printf("player %d played card %d %d\n", in.data.move.player, in.data.move.play_card.suit, in.data.move.play_card.weight);
break;
case SCORE_UPDATE:
printf("\nplayer %d won last hand!\n", in.data.score.lastwin);
printf("scores: %d %d\n", in.data.score.scores[0], in.data.score.scores[1]);
break;
case DEAL_TYPE:
memcpy(&hand[in.data.deal.rec_place], &in.data.deal.deal_card, sizeof(struct card));
/*
update_cards();
*/
break;
case INFORM_TYPE:
printf("server send INFORM_TYPE. Not at start of game\n");
break;
case MOVE_EXPECTED:
if(in.data.move.player != my_number)
break;
out.type = MOVE_TYPE;
out.data.move.player = my_number;
do
{
update_cards();
printf("hey, hosehead, enter a card\n");
fgets(buf, 80, stdin);
sscanf(buf, "%d %d", &out.data.move.play_card.suit, &out.data.move.play_card.weight);
write(server_fd, &out, sizeof(struct packet));
read(server_fd, &in, sizeof(struct packet));
if(in.type == ILLEGAL_MOVE)
printf("illegal card %d %d\n", out.data.move.play_card.suit, out.data.move.play_card.weight);
}
while(in.type == ILLEGAL_MOVE);
hand[in.data.ok.cardpos].suit = -1;
hand[in.data.ok.cardpos].weight = -1;
}
}
}
int start_client(char *hostname, int port)
{
struct sockaddr_in addr;
struct protoent *proto;
struct hostent *host;
struct packet p;
proto = getprotobyname("tcp");
if(!proto)
{
printf("tcp not supported here.\n");
return 0;
}
host = gethostbyname(hostname);
if(!host)
{
printf("cannot find host '%s'\n", host);
return 0;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);
memcpy((char *)&addr.sin_addr, (char *)(*host->h_addr_list), host->h_length);
server_fd = socket(PF_INET, SOCK_STREAM, proto->p_proto);
if(server_fd == -1)
{
perror("socket");
return 0;
}
printf("Attemping to connect to port %i of server %s.\n", port, hostname);
if(connect(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
perror("connect");
return 0;
}
read(server_fd, &p, sizeof(struct packet));
printf("# players %d, play_type %d. I player # %d\n", p.data.inform.numplayers, p.data.inform.play_type,
p.data.inform.yournumber);
numplayers = p.data.inform.numplayers;
play_type = p.data.inform.play_type;
my_number = p.data.inform.yournumber;
return 1;
}